package com.bxd.baodan.probe;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.ConnectivityManager;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.widget.Toast;

import com.bxd.baodan.App;
import com.bxd.baodan.app.Constant;
import com.bxd.baodan.app.LoginInfo;
import com.bxd.baodan.interfaces.OnNetFailListener;
import com.bxd.baodan.util.DesUtil;
import com.bxd.baodan.util.JSONUtil;
import com.bxd.baodan.util.LogUtil;
import com.bxd.baodan.util.net.M509TrustManager;
import com.bxd.baodan.util.net.MyHostnameVerifier;

import org.json.JSONException;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;


/**
 * 网络接口,post请求string或者get请求json,里面只包含一个线程,只能同时发送一个网络请求
 *
 * @author oldfeel
 */
public class ProbeNetUtil extends Handler {

    private static final int TIME_OUT = 8*1000;
  private static final String APP_SECRET   = "xbxiH4QWBPHRXvm0";
    private Context activity;
    Map<String, Object> params = new HashMap<String, Object>();
    private Thread requestThread;
    private String path;


    /**
     * 构造一个netapi对象
     *
     * @param activity
     * @param api      这次请求需要调用的api
     */
    public ProbeNetUtil(Context activity, String api) {
        this.activity = activity;
        path = api;

    }





    /**
     * 添加参数
     *
     * @param key
     * @param value
     */
    public void setParams(String key, Object value) {
        if (!isEmpty(key) && !isEmpty(value)) {
            params.put(key.trim(), value.toString().trim());// *.trim(),取消首尾空格
        }
    }



    /**
     * 检查该参数是否有内容,没有的话就不用添加了
     *
     * @param str
     * @return true为没有内容, false为有内容
     */
    public boolean isEmpty(Object str) {
        if (str == null || str.toString().length() == 0)
            return true;
        else
            return false;
    }



    /**
     * 发起一个post请求,返回string对象
     *
     * @param stringListener true 为加载缓存，false为不加载缓存
     */


    public void postRequest(final String text,
                            final RequestStringListener stringListener) {

        if (!isNetworkConnect(activity)) {
            App.getContext().sendBroadcast(
                    new Intent(Constant.ACTION_NO_INTERNET));
            return;
        }
        Runnable task = new Runnable() {

            @Override
            public void run() {
                try {
                    final String result = postStringResult()/*okPost()*/;

                    //打断点
                    if (requestThread.isInterrupted()) {
                        return;
                    }
                    if (result == null || TextUtils.isEmpty(result)) {
                        netError();
                        return;
                    }
                    post(new Complete() {

                        @Override
                        public void run() {
                            super.run();
                            if (stringListener != null) {
                                stringListener.onComplete(result);
                            }
                        }
                    });
                } catch (Exception e) {
                    netError();
                    e.printStackTrace();
                }

            }
        };
        requestThread = new Thread(task);
        requestThread.start();
    }



    /**
     * 网络连接错误或返回数据为空
     */
    protected void netError() {
        if (Looper.myLooper() == null) {
            Looper.prepare();
        }
        post(new Complete() {
            @Override
            public void run() {
                super.run();
                if (failListener != null) {
                    failListener.onError();
                }
            }
        });
    }


    /**
     * 发送post上传文件,获取字符串结果
     * <p>
     * true为加载缓存，false为不加载缓存
     *
     * @throws JSONException
     * @throws NameNotFoundException
     * @throws Exception
     */
    public String postStringResult() throws SocketTimeoutException,
            JSONException, NameNotFoundException {
        try {

            currentTime = System.currentTimeMillis();
            URL url = new URL(path);
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, new TrustManager[]{new M509TrustManager()},
                    null);
            HttpsURLConnection
                    .setDefaultSSLSocketFactory(sc.getSocketFactory());
            HttpsURLConnection
                    .setDefaultHostnameVerifier(new MyHostnameVerifier());
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            // httpClient.getParams().setParameter("http.useragent",
            // getUserAgent());
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setRequestMethod("POST");
            conn.setConnectTimeout(TIME_OUT);
            conn.setReadTimeout(TIME_OUT);
            conn.connect();
            DataOutputStream outStream = new DataOutputStream(
                    conn.getOutputStream());
            StringBuilder builder = new StringBuilder();
            if (params != null) {
                md5Map(params);

                for (String name : params.keySet()) {
                    builder.append("&"
                            + URLEncoder.encode(name, "utf-8")
                            + "="
                            + URLEncoder.encode(params.get(name).toString(),
                            "utf-8"));
                }
                builder.deleteCharAt(0);
                outStream.writeBytes(builder.toString());


            }
            LogUtil.e("get pro url ------> " + "\n" + path + builder.toString());

            if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
                StringBuffer out = new StringBuffer();
                BufferedReader input = new BufferedReader(
                        new InputStreamReader(conn.getInputStream()));
                String line = null;
                while ((line = input.readLine()) != null) {
                    out.append(line);
                }
                input.close();

                String data = out.toString();
                LogUtil.e("get pro data ----> " + "\n" + data);
                return data;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }



    private Map<String, Object> md5Map(Map<String, Object> params) {
        try {
            params.remove("sign");  // FIXME: 2017/7/15 修复签名不对的bug,由于涉及到修改框架,暂时只做简单处理
        } catch (Exception e) {
            e.printStackTrace();
        }

        currentTime = System.currentTimeMillis();
        setParams("request_date",currentTime/1000);

        Iterator iter = params.entrySet().iterator();
        StringBuilder pp = new StringBuilder();
        while (iter.hasNext()) {
            Map.Entry entry = (Map.Entry) iter.next();
            String key = entry.getKey().toString();
            String val = entry.getValue().toString();
            pp.append(key + "=" + val + ",");

        }

        // 进行排序加密
        List<Map.Entry<String, Object>> mHashMapEntryList = new ArrayList<>(params.entrySet());

        Collections.sort(mHashMapEntryList,
                new Comparator<Map.Entry<String, Object>>() {

                    @Override
                    public int compare(Map.Entry<String, Object> firstMapEntry,
                                       Map.Entry<String, Object> secondMapEntry) {
                        return firstMapEntry.getKey().compareTo(
                                secondMapEntry.getKey());
                    }
                });

        StringBuilder sb = new StringBuilder();


        for (int i = 0; i < mHashMapEntryList.size(); i++) {
            if (i == 0) {
                sb.append(mHashMapEntryList.get(i).getKey() + "="
                        + mHashMapEntryList.get(i).getValue().toString());
            } else {
                sb.append("&" + mHashMapEntryList.get(i).getKey() + "="
                        + mHashMapEntryList.get(i).getValue().toString());

            }
        }

        String uri = "/message/post/";
        String sign = uri + "?" + sb + APP_SECRET;
        LogUtil.e("sign: " + sign);
        String signature = DesUtil.md5(sign.toString());

        params.put("sign", signature);

        return params;
    }

    class Complete implements Runnable {
        @Override
        public void run() {

            requestThread.interrupt();
        }
    }


    /**
     * 判断网络连接
     */
    public static boolean isNetworkConnect(Context context) {
        try {
            ConnectivityManager cm = (ConnectivityManager) context
                    .getSystemService(Context.CONNECTIVITY_SERVICE);
            cm.getActiveNetworkInfo();
            if (cm.getActiveNetworkInfo() != null) {
                return cm.getActiveNetworkInfo().isAvailable();
            }
        } catch (Exception e) {
            // TODO: handle exception
        }
        return false;
    }







    /**
     * 请求string的监听
     */
    public abstract static class RequestStringListener implements NetListener {
        /**
         * 返回字符串
         */
        public abstract void onComplete(String result);

        @Override
        public void onError(String result) {
            if (JSONUtil.getCode(result) == 8000) {
                //token过期
                LoginInfo.getInstance(App.getContext()).cancelLogin(App.getContext());
                App.getContext().sendBroadcast(new Intent(Constant.ACTION_LOGIN_LOGINOUT));
            }
            Toast.makeText(App.getContext(), JSONUtil.getMessage(result), Toast.LENGTH_SHORT).show();
        }
    }

    public interface NetListener {
        /**
         * 返回字符串
         */
        void onError(String result);

        void onComplete(String result);
    }


    private OnNetFailListener failListener;
    private Long currentTime;







}
